#include <stdlib.h>
#include "zomby.h"
#include "animation.h"
#include "point2.h"
#include "statectrl.h"
#include "globals.h"
#include "frame.h"
#include "rect.h"

Zomby::Zomby(){
	ani_dead =NULL;	
	ani_stand =NULL;	
	ani_run =NULL;
	ani_fall =NULL;
	ani_bite =NULL;
	ani_kick =NULL;
	ani_rot =NULL;
}

Zomby::~Zomby(){

	unsigned int i;

	delete ani_dead;	
	ani_dead =NULL;	
	delete ani_stand;	
	ani_stand =NULL;	
	delete ani_run;
	ani_run =NULL;
	delete ani_fall;
	ani_fall =NULL;
	delete ani_rot;
	ani_rot =NULL;

	for(i=0; i<ani_kick->nFrames; i++){
		delete kick[i];
		kick[i] =NULL;
	}
	delete[] kick;
	kick =NULL;
	delete ani_kick;
	ani_kick =NULL;

	for(i=0; i<ani_bite->nFrames; i++){
		delete bite[i];
		bite[i] =NULL;
	}
	delete[] bite;
	bite =NULL;
	delete ani_bite;
	ani_bite =NULL;
}

void Zomby::setStill(int argument){

	cur_animation =ani_stand;
	set_func =still;

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	new_frame =true;
	this->state =STATE_STILL;
};

void Zomby::setMove(int argument){

	cur_animation =ani_run;
	set_func =move;

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	new_frame =true;
	this->state =STATE_MOVE;
};

void Zomby::setJump(int argument){

	cur_animation =ani_fall;
	set_func =jump;

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	new_frame =true;
	this->state =STATE_JUMP;
};

void Zomby::setFall(int argument){

//	if(this->state==STATE_BORN)
//		layer +=3;				//? constatnt?

	cur_animation =ani_fall;
	set_func =fall;

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	new_frame =true;
	this->state =STATE_FALL;
};

void Zomby::setDead(int argument){

	cur_animation =ani_dead;
	set_func =die;

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	new_frame =true;
	this->state =STATE_DEAD;
};

void Zomby::setAttack(int argument){

	int rnd;

	rnd =rand()%2;		//? constatnt?
	if(rnd==0)
		cur_animation =ani_bite;
	else
		cur_animation =ani_kick;

	set_func =punch_f;

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	new_frame =true;
	this->state =STATE_ATTACK;
};

/*
void Zomby::setState(int state, int argument){

	int rnd;
	
	switch(state){
	case STATE_DEAD:
		cur_animation =ani_dead;
//		set_func =characterDead;
		break;
	case STATE_STILL:
		cur_animation =ani_stand;
//		set_func =characterStill;
		break;
	case STATE_MOVE:
		cur_animation =ani_run;
//		set_func =characterMove;
		break;
	case STATE_FALL:
		if(this->state==STATE_BORN)
			layer +=3;				//? constatnt?
		cur_animation =ani_fall;
//		set_func =characterFall;
		break;
	case STATE_BORN:
	case STATE_JUMP:
		cur_animation =ani_fall;
//		set_func =characterFall;
		break;
	case STATE_ATTACK:
		rnd =rand()%2;		//? constatnt?
		if(rnd==0)
			cur_animation =ani_bite;
		else
			cur_animation =ani_kick;
//		set_func =characterFall;
		break;
	case STATE_ROT:
		cur_animation =ani_rot;
//		set_func =characterFall;
		break;
	}

	cur_animation->begin_time =0;
	cur_animation->cur_frame =0;
	this->state =state;
	new_frame =true;
}
*/

void Zomby::update(Level* level, Point2* acc, float dt){

	int passed_time;
	int passed_frames;
	div_t div_tmp;
	unsigned int fr1;

	// update animation
	fr1 =cur_animation->cur_frame;

	cur_animation->begin_time +=static_cast<unsigned int>(dt);
	passed_time =cur_animation->begin_time;
	passed_frames =int((float)passed_time/(1000.0f/cur_animation->fps));
	div_tmp =div(passed_frames, cur_animation->nFrames);
	cur_animation->cur_frame =div_tmp.rem;

	(this->*set_func)(level, acc, dt);
/*
	switch(state){
	case STATE_STILL:
		still(level, acc, dt);
		break;
	case STATE_MOVE:
		move(level, acc, dt);
		break;
	case STATE_FALL:
		fall(level, acc, dt);
		break;
	case STATE_BORN:
	case STATE_JUMP:
		jump(level, acc, dt);
		break;
	case STATE_DEAD:
		die(level, acc, dt);
		break;
	case STATE_ATTACK:
		punch_f(level, acc, dt);
		break;
//	case STATE_ROT:
//		rot(level, acc, dt);
//		break;
	}
*/

	if(cur_animation->cur_frame!=fr1 || new_frame){
			srcPlay(this); 
	}
	new_frame =false;

//	this->set_func(level, acc, dt);
}

void Zomby::still(Level* level, Point2* acc, float dt){

	if(attack){
//		setState(STATE_ATTACK, 0);
		setAttack(0);
	}

	if(moveXplus){
		velocity->x =speed;
		orientation->x =1;
//		setState(STATE_MOVE, 0);
		setMove(0);
		return;
	}
	else if(moveXminus){
		velocity->x =-speed;	
		orientation->x =-1;
//		setState(STATE_MOVE, 0);
		setMove(0);
		return;
	}

	genStill(level, this);
}

void Zomby::move(Level* level, Point2* acc, float dt){

	if(attack){
//		setState(STATE_ATTACK, 0);
		setAttack(0);
	}

	if(moveXplus){
		velocity->x =speed;
		orientation->x =1;
	}
	else if(moveXminus){
		velocity->x =-speed;	
		orientation->x =-1;
	}
	else{
		velocity->x =0;
//		setState(STATE_STILL, 0);
		setStill(0);
	}

	genMove(level, this, dt);
}

void Zomby::fall(Level* level, Point2* acc, float dt){

	if(moveXplus){
		velocity->x =speed;
		orientation->x =1;
	}
	else if(moveXminus){
		velocity->x =-speed;	
		orientation->x =-1;
	}

	genFall(level, this, acc, dt);
}

void Zomby::die(Level* level, Point2* acc, float dt){

	// find velocity vector
	*velocity += *acc*(dt*0.001f);
	// find translation vector
	*position +=*velocity*(float)dt*0.1f; // 100cm/1000ms
}

void Zomby::jump(Level* level, Point2* acc, float dt){

	// find velocity vector
	if(special)
		*velocity += *acc*(dt*0.001f);
//		*velocity += *acc*(dt*jump_mult*0.001f);	//?
	else
		*velocity += *acc*(dt*0.001f);
	if(moveXplus){
		velocity->x =speed;
		orientation->x =1;
	}
	else if(moveXminus){
		velocity->x =-speed;	
		orientation->x =-1;
	}
	else {
		velocity->x =0;
	}

	genJump(level, this, dt);
}

void Zomby::punch_f(Level* level, Point2* acc, float dt){

	genStill(level, this);

//	if(moveYplus){
//		aim =AIM_UP;
//	}
///	else
//	if(moveYminus){
//		aim =AIM_DOWN;
//	}
//	else{
//		aim =AIM_STRAIGHT;
//	}
//
	if(moveXminus)
		orientation->x =-1;
	else
	if(moveXplus)
		orientation->x =1;

	int passed_time =cur_animation->begin_time;
	if(passed_time>=cur_animation->nFrames*(1000.0f/cur_animation->fps)){
//		setState(STATE_STILL, 0);
		setStill(0);
		return;
	}
}

/*
void Zomby::rot(Level* level, Point2* acc, float dt){

	int passed_time =cur_animation->begin_time;

	if(passed_time>=cur_animation->nFrames*(1000.0f/cur_animation->fps)){
		active =false;
		return;
	}
//	genStill(level, this);
}
*/
float Zomby::get_xLo(){

	return position->x + cur_animation->frames[cur_animation->cur_frame]->body->xLo;
}

float Zomby::get_xHi(){

	return position->x + cur_animation->frames[cur_animation->cur_frame]->body->xHi;
}

float Zomby::get_yHi(){

	return position->y + cur_animation->frames[cur_animation->cur_frame]->body->yHi;
}

float Zomby::get_yLo(){

	return position->y + cur_animation->frames[cur_animation->cur_frame]->body->yLo;
}

float Zomby::get_pic_xLo(){

	return position->x + cur_animation->frames[cur_animation->cur_frame]->box->xLo;
}

float Zomby::get_pic_xHi(){

	return position->x + cur_animation->frames[cur_animation->cur_frame]->box->xHi;
}

float Zomby::get_pic_yHi(){

	return position->y + cur_animation->frames[cur_animation->cur_frame]->box->yHi;
}

float Zomby::get_pic_yLo(){

	return position->y + cur_animation->frames[cur_animation->cur_frame]->box->yLo;
}

Rect* Zomby::getBody(){

	return cur_animation->frames[cur_animation->cur_frame]->body;
}

Rect* Zomby::getBox(){

	return cur_animation->frames[cur_animation->cur_frame]->box;
}
